package com.cloud.common.util;

import com.cloud.common.constant.GenConstants;
import com.cloud.generator.domain.GenTable;
import com.cloud.generator.domain.GenTableColumn;
import com.cloud.utils.StringUtils;

import java.util.Arrays;

/**
 * 代码生成器 工具类
 *
 * @author yzj
 */
public class GenUtils {

    /**
     * 初始化表信息
     */
    public static void initTable(GenTable genTable, String userName) {
        String className = tableToClassName(genTable);
        genTable.setClassName(className);
        genTable.setPackageName(VelocityUtils.PACKAGE_PATH);
        genTable.setModuleName(genTable.getModuleName());
        genTable.setBusinessName(StringUtils.uncapitalize(className));
        genTable.setFunctionName(genTable.getTableComment());
        genTable.setFunctionAuthor(genTable.getFunctionAuthor());
        genTable.setCreateBy(userName);
    }

    /**
     * 初始化列属性字段
     */
    public static void initColumnField(GenTableColumn column, GenTable table) {
        String dataType = getDbType(column.getColumnType());
        String columnName = column.getColumnName();
        column.setTableId(table.getTableId());
        column.setCreateBy(table.getCreateBy());
        // 设置驼峰式字段名
        column.setJavaField(StringUtils.toCamelCase(columnName));
        column.setJavaType(GenConstants.TYPE_STRING);
        column.setQueryType(GenConstants.QUERY_EQ);
        // 判断是否是字符串类型
        if (arraysContains(GenConstants.COLUMN_TYPE_STR, dataType)
                || arraysContains(GenConstants.COLUMN_TYPE_TEXT, dataType)) {
            // 字符串长度超过500设置为文本域
            Integer columnLength = getColumnLength(column.getColumnType());
            String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMN_TYPE_TEXT, dataType)
                    ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
            column.setHtmlType(htmlType);
            // 判断是否是时间类型
        } else if (arraysContains(GenConstants.COLUMN_TYPE_TIME, dataType)) {
            column.setJavaType(GenConstants.TYPE_DATE);
            column.setHtmlType(GenConstants.HTML_DATETIME);
            // 判断是否是数值类型
        } else if (arraysContains(GenConstants.COLUMN_TYPE_NUMBER, dataType)) {
            column.setHtmlType(GenConstants.HTML_INPUT);
            // 如果是浮点型,统一用BigDecimal
            String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(),
                    "(", ")"), ",");
            if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) {
                column.setJavaType(GenConstants.TYPE_BIG_DECIMAL);
                // 如果是整形
            } else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) {
                column.setJavaType(GenConstants.TYPE_INTEGER);
                // 如果是长整形
            } else {
                column.setJavaType(GenConstants.TYPE_LONG);
            }
        }
        // 插入字段（默认所有字段都需要插入）
        column.setIsInsert(GenConstants.REQUIRE);
        // 编辑字段
        if (!arraysContains(GenConstants.COLUMN_NAME_NOT_EDIT, columnName) && !column.checkPk()) {
            column.setIsEdit(GenConstants.REQUIRE);
        }
        // 列表字段
        if (!arraysContains(GenConstants.COLUMN_NAME_NOT_LIST, columnName) && !column.checkPk()) {
            column.setIsList(GenConstants.REQUIRE);
        }
        // 查询字段
        if (!arraysContains(GenConstants.COLUMN_NAME_NOT_QUERY, columnName) && !column.checkPk()) {
            column.setIsQuery(GenConstants.REQUIRE);
        }
        // 查询字段类型
        if (StringUtils.endsWithIgnoreCase(columnName, "name")) {
            column.setQueryType(GenConstants.QUERY_LIKE);
        }
        // 状态字段设置单选框
        if (StringUtils.endsWithIgnoreCase(columnName, "status")) {
            column.setHtmlType(GenConstants.HTML_RADIO);
            // 类型&性别字段设置下拉框
        } else if (StringUtils.endsWithIgnoreCase(columnName, "type")
                || StringUtils.endsWithIgnoreCase(columnName, "sex")) {
            column.setHtmlType(GenConstants.HTML_SELECT);
            // 图片字段设置图片上传控件
        } else if (StringUtils.endsWithIgnoreCase(columnName, "image")) {
            column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD);
            // 文件字段设置文件上传控件
        } else if (StringUtils.endsWithIgnoreCase(columnName, "file")) {
            column.setHtmlType(GenConstants.HTML_FILE_UPLOAD);
            // 内容字段设置富文本控件
        } else if (StringUtils.endsWithIgnoreCase(columnName, "content")) {
            column.setHtmlType(GenConstants.HTML_EDITOR);
        }
    }

    /**
     * 校验数组是否包含指定值
     *
     * @param arr         数组
     * @param targetValue 值
     * @return 是否包含
     */
    public static boolean arraysContains(String[] arr, String targetValue) {
        return Arrays.asList(arr).contains(targetValue);
    }


    /**
     * 表名转换成类名
     *
     * @return 类名
     */
    public static String tableToClassName(GenTable genTable) {
        String tableName = genTable.getTableName(); //表名称
        if (StringUtils.isNotEmpty(genTable.getTablePrefix())) {
            String[] searchList = StringUtils.split(genTable.getTablePrefix(), ",");
            // 批量替换表名前缀
            for (String searchString : searchList) {
                if (genTable.getTableName().startsWith(searchString)) {
                    tableName = tableName.replaceFirst(searchString, "");
                    break;
                }
            }
        }
        return StringUtils.convertToCamelCase(tableName);
    }

    /**
     * 获取数据库类型字段
     *
     * @param columnType 列类型
     * @return 截取后的列类型
     */
    public static String getDbType(String columnType) {
        if (StringUtils.indexOf(columnType, "(") > 0) {
            return StringUtils.substringBefore(columnType, "(");
        } else {
            return columnType;
        }
    }

    /**
     * 获取字段长度
     *
     * @param columnType 列类型
     * @return 截取后的列类型
     */
    public static Integer getColumnLength(String columnType) {
        if (StringUtils.indexOf(columnType, "(") > 0) {
            String length = StringUtils.substringBetween(columnType, "(", ")");
            return Integer.valueOf(length);
        } else {
            return 0;
        }
    }

}
